package com.genericity.demo08;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        System.out.println("类型擦除！");
        ArrayList<Integer> intList = new ArrayList<>();
        ArrayList<String> strList = new ArrayList<>();
        /**
         * 获取实质 intList 和 strList 数据类型
         * 获取的结果都是 ArrayList
         * 但是我们上面各自定义为 Integer 和 String 类型
         * 证明在泛型信息只存在编译阶段，JVM运行阶段被擦除了
         */
        System.out.println(intList.getClass().getSimpleName()); // ArrayList
        System.out.println(strList.getClass().getSimpleName()); // ArrayList
        System.out.println(intList.getClass() == strList.getClass()); // true
        System.out.println("=========");
        /**
         * 擦除类型分为：
         * 1、无限制擦除（把传入进来的数据类型替换成 Object 类型）
         * 2、有限制擦除
         */
        // 定义Integer类型泛型类
        Erasure<Integer> intErasure = new Erasure<>();
        // 利用反射 获取Erasure的字节码Class对象
        Class<? extends Erasure> cls = intErasure.getClass();
        // 获取所有成员变量信息
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 答应字段名称以及数据类型
            // 打印结果：字段：key 数据类型：Object
            System.out.println("字段："+declaredField.getName()+" 数据类型："+declaredField.getType().getSimpleName());
        }

        System.out.println("===============");
        /**
         * 泛型方法擦除
         * 1、无限制擦除
         * 2、有限制擦除
         */
        // 获取所有的方法
        Method[] declaredMethods = cls.getDeclaredMethods();
        // 打印所有的方法
        for (Method declaredMethod : declaredMethods) {
            // 打印方法名称和返回的数据类型
            System.out.println("名称："+declaredMethod.getName()+"："+declaredMethod.getReturnType().getSimpleName());
            /**
             * 打印结果
             * 名称：run：List 方法的数据类型上限为 List
             * 名称：getKey：Number 由于是 <T extends Number> 所以返回数据类型也是 Number
             * 名称：setKey：void
             * 名称：go：Object 没有上限 默认就是 Object，下限也是
             */
        }
    }
}
